interface Status {
    SUCCESS: string
    ERROR: string,
    TIMEOUT: string
}
interface SetParams {
    key: string,
    value: any,
    time?: string | number
}
interface Data {
    value: any,
    time: string | number
}
interface localStatus {
    state: string,
    key?: string,
    data?: Data | null,
    error?: any,
    message?: string
}
export default class LocalStorage {
    storage: Storage = localStorage || window.localStorage
    status: Status = {
        SUCCESS: "SUCCESS", //成功
        ERROR: "ERROR",   //失败
        TIMEOUT: "TIMEOUT", //过期
    }
    $timeFlag: boolean
    $projectName: string
    /**
     * 
     * @param timeFlag 是否开启时效存储 
     * @param projectName 项目名称
     */
    constructor(timeFlag: boolean = true, projectName: string = 'PROJECT') {
        this.$timeFlag = timeFlag;
        this.$projectName = projectName;
    }
    /**
     * 
     * @param key key
     * @param value value
     * @param callback 回调函数
     * @param time 设置有效期 max 无线  否则就是一个时间戳
     */
    set({ key, value, time = 'MAX' }: SetParams): Promise<localStatus> {
        let data: Data = {
            value,
            time
        }
        return new Promise((resolve, reject) => {
            if (!this.isEmpty(key)) {
                reject({
                    state: this.status.ERROR,
                    message: "You cannot pass in undefined null '' "
                })
            }
            try {
                this.storage.setItem(`${this.$projectName}_${key}`, JSON.stringify(data))
                resolve({
                    state: this.status.SUCCESS,
                    key,
                    data
                })
            }
            catch (e) {
                reject({
                    state: this.status.ERROR,
                    error: e,
                    key,
                    data
                })
            }
        })

    }
    get(key: string): Promise<localStatus> {
        return new Promise(async (resolve, reject) => {
            let value: any = this.storage.getItem(`${this.$projectName}_${key}`)
            if (!this.isEmpty(value)) {
                reject({
                    state: this.status.ERROR,
                    message: "An invalid value"
                })
            } else {
                let nowDate: number = new Date().getTime();
                let data: Data = JSON.parse(this.storage.getItem(`${this.$projectName}_${key}`) as any)
                if (value.time === 'MAX') {
                    resolve({
                        state: this.status.SUCCESS,
                        data: data.value,
                        message: "success"
                    })
                }else{
                   if(nowDate > data.time){
                       try{
                        await this.remove(key)
                        resolve({
                           state:this.status.TIMEOUT,
                           data:null,
                        })
                       }
                       catch(e){
                           reject({
                               state:this.status.ERROR,
                               message:"An invalid value",
                               error:e
                           })
                       }
                   }else{
                       resolve({
                           state:this.status.SUCCESS,
                           data:data.value,
                           message:"success"
                       })
                   }
                }
            }
        })
    }
    remove(key:string):Promise<localStatus> {
        let value:any = this.storage.getItem(`${this.$projectName}_${key}`)
        return new Promise((resolve,reject)=>{
            if(!this.isEmpty(value)){
               reject({
                   state:this.status.ERROR,
                   message:"An invalid value"
               })
            }else{
                this.storage.removeItem(`${this.$projectName}_${key}`)
                resolve({
                    state:this.status.SUCCESS,
                    message:"success"
                })
            }
        })
 
    }
    isEmpty(key: any): boolean {
        if (key !== "" && key !== null && key !== undefined) {
            return true
        } else {
            return false
        }
    }
    clear(): Promise<localStatus> {
        return new Promise((resolve, reject) => {
            try {
                this.storage.clear()
                resolve({ state: this.status.SUCCESS })
            }
            catch (e) {
                reject({ state: this.status.ERROR })
            }
        })
    }
}       
